﻿using EMall.IdentityService.Menus;
using EMall.IdentityService.PermissionGrants;
using EMall.IdentityService.Users;
using EMall.Query;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;

namespace EMall.IdentityService.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    [Authorize]
    public class AuthController : ControllerBase
    {
        private readonly UserManager<User> _userManager;
        private readonly IQueryService _queryService;
        public AuthController(
            UserManager<User> userManager,
            IQueryService queryService)
        {
            _userManager = userManager;
            _queryService = queryService;
        }
        [HttpGet]
        public async Task<UserMenuTree> GetUserMenuTreeAsync()
        {
            var permissions = await GetUserPermissionsAsync();
            var menus = await _queryService.GetQueryable<Menu>()
                .Where(o => permissions.Contains(o.Id.ToString()))
                .Select(o => new UserMenuTree
                {
                    Id = o.Id,
                    Name = o.Name,
                    Code = o.Code,
                    Type = o.Type,
                    ParentId = o.ParentId,
                    Enabled = o.Enabled,
                    Permission = o.Permission,
                    Route = o.Route,
                    Path = o.Path,
                    Extensions = o.Extensions
                })
                .ToListAsync();
            return TreeBuilder.Build<UserMenuTree, int>(menus,0);
        }
        [HttpGet]
        public async Task<IEnumerable<UserMenuListDto>> GetUserMenuListAsync()
        {
            var permissions = await GetUserPermissionsAsync();
            return await _queryService.GetQueryable<Menu>()
                .Where(o => permissions.Contains(o.Id.ToString()))
                .Select(o => new UserMenuListDto
                {
                    Name = o.Name,
                    Code = o.Code,
                    Type = o.Type,
                    ParentId = o.ParentId,
                    Enabled = o.Enabled,
                    Permission = o.Permission,
                    Route = o.Route,
                    Path = o.Path,
                    Extensions = o.Extensions
                })
                .ToListAsync();
        }
        private async Task<IEnumerable<string>> GetUserPermissionsAsync()
        {
            var user = await _userManager.GetUserAsync(HttpContext.User);
            var roles = await _userManager.GetRolesAsync(user);
            return await _queryService.GetQueryable<PermissionGrant>()
                .Where(o => (o.Type == PermissionGrantType.R && roles.Contains(o.Key)) || (o.Type == PermissionGrantType.U && user.Id.ToString() == o.Key))
                .Select(o => o.Permission)
                .ToListAsync();
        }
    }
    public class UserMenuTree : Tree<UserMenuTree, int>
    {
        public string Name { get; set; }
        public string Code { get; set; }
        public MenuType Type { get; set; }
        public bool Enabled { get; set; }
        public string Permission { get; set; }
        public string Route { get; set; }
        public string Path { get; set; }
        public string Extensions { get; set; }
    }
    public class UserMenuListDto
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Code { get; set; }
        public MenuType Type { get; set; }
        public int ParentId { get; set; }
        public bool Enabled { get; set; }
        public string Permission { get; set; }
        public string Route { get; set; }
        public string Path { get; set; }
        public string Extensions { get; set; }
    }
}
